package concat

import (
	"errors"
	"os"
	"path"
	"sync"
	"time"
)

var (
	ErrCacheExpire   = errors.New("cache expires")
	ErrCacheNotExist = errors.New("cache does not exist")
)

type FileCache struct {
	*sync.RWMutex
	Dir    string
	Expire time.Duration
}

func NewFileCache(dir string, expire time.Duration) FileCache {
	return FileCache{RWMutex: new(sync.RWMutex), Dir: dir, Expire: expire}
}

func (fc *FileCache) key(key string) string {
	return path.Join(fc.Dir, Md5([]byte(key)))
}

func (fc *FileCache) Set(key string, data []byte) error {
	fc.Lock()
	defer fc.Unlock()
	return WriteFile(fc.key(key), data)
}

func (fc *FileCache) Delete(key string) error {
	fc.Lock()
	defer fc.Unlock()
	return os.Remove(fc.key(key))
}

func (fc *FileCache) Get(key string) ([]byte, error) {
	fc.RLock()
	defer fc.RUnlock()
	key = fc.key(key)
	fileinfo, err := os.Stat(key)

	if err != nil {
		if err == os.ErrNotExist {
			return nil, ErrCacheNotExist
		} else {
			return nil, err
		}
	}

	// 如果缓存过期
	if time.Since(fileinfo.ModTime()) > fc.Expire {
		return nil, ErrCacheExpire
	}
	return ReadFile(key)
}
